﻿namespace Radar.Test
{
    using NUnit.Framework;

    [TestFixture]
    public class CircularReferencesTest
    {
        private interface IA { }
        private interface IB { }
        private interface IC { }

        private class A : IA { public A(IC c) { } }
        private class B : IB { public B(IA a) { } }
        private class C : IC { public C(IB b) { } }

        private IContainer container;

        [SetUp]
        public void SetUp()
        {
            container = new Container();

            container.Register<IA, A>();
            container.Register<IB, B>();
            container.Register<IC, C>();
        }

        [Test, ExpectedException(typeof(CircularReferenceException))]
        public void WillThrowOnCircularDependenceForFirstClass()
        {
            container.Resolve<IA>();
        }

        [Test, ExpectedException(typeof(CircularReferenceException))]
        public void WillThrowOnCircularDependenceForSecondClass()
        {
            container.Resolve<IB>();
        }

        [Test, ExpectedException(typeof(CircularReferenceException))]
        public void WillThrowOnCircularDependenceForThirgClass()
        {
            container.Resolve<IC>();
        }

        [Test, ExpectedException(typeof(CircularReferenceException))]
        public void WillThrowOnCircularDependenceWithSingletonLifetime()
        {
            container = new Container();

            container.Register<IA, A>().WithLifetime(Lifetime.Singleton);
            container.Register<IB, B>().WithLifetime(Lifetime.Singleton);
            container.Register<IC, C>().WithLifetime(Lifetime.Singleton);

            container.Resolve<IC>();
        }

        [Test, ExpectedException(typeof(CircularReferenceException))]
        public void WillThrowOnCircularDependenceWithThreadLocalLifetime()
        {
            container = new Container();

            container.Register<IA, A>().WithLifetime(Lifetime.ThreadLocal);
            container.Register<IB, B>().WithLifetime(Lifetime.ThreadLocal);
            container.Register<IC, C>().WithLifetime(Lifetime.ThreadLocal);

            container.Resolve<IC>();
        }
    }
}